<template>
  <view class="dtu-wrapper">
    <view class="search" @click="getDevice">选择设备</view>
    <view class="name" v-if="name">{{ name }}</view>
    <view class="title">
      <text>设备UUID:</text>
      <text class="uuid">{{ name || "-" }}</text>
      <text v-if="isConnect" :class="isConnect ? 'icon online' : 'icon offline'"></text>
    </view>
    <view class="item" v-for="(item, ids) in info" :key="ids">
      <text>{{ item }}: </text>
      <u--textarea
        class="textarea"
        v-model="optData[ids]"
        :placeholder="'请输入' + item"
        autoHeight
        :maxlength="1024"
        adjustPosition
      ></u--textarea>
      <text class="btn" @click="upEvent(optData[ids], ids)">确认</text>
    </view>
    <view class="footer">
      <u-button
        type="primary"
        :disabled="!isSet"
        @click="getSetting"
        text="获取配置"
      ></u-button>
      <u-button type="success" @click="toSys('F77F', 1)" text="升级系统"></u-button>
      <u-button type="warning" @click="toSys('F00F', 2)" text="重启设备"></u-button>
    </view>
    <u-picker
      :show="show"
      :columns="columns"
      keyName="name"
      @confirm="onConfirm"
      @cancel="onCancel"
    ></u-picker>
    <u-toast ref="uToast"></u-toast>
  </view>
</template>

<script>
import { serverUUID, readId, writeId, CODE, WRITE } from "./conf.js";
import {
  openBluetooth,
  blueDevices,
  createBLEC,
  closeBLEC,
  notifyBLEC,
  writeBLEC,
  readBLEC,
} from "@/utils/blec.js";
import {
  objArraySort,
  setValstr,
  hexToString,
  arrayBufferToString,
} from "@/utils/index.js";
export default {
  data() {
    return {
      show: false,
      columns: [[]],
      name: "",
      deviceId: "",
      timer: null,
      idx: 0,
      isOpen: false, // 是否打开蓝牙
      isSet: false, // 获取配置按钮是否可用
      isConnect: false, // 是否连接设备
      optData: [],
      info: [
        "服务器IP",
        "端 口 号",
        // "用 户 名",
        // "密  码",
        "上报间隔",
        "上报topic",
        "订阅topic",
        "响应topic",
      ],
    };
  },
  mounted() {
    this.init();
  },
  beforeDestroy() {
    // 关闭蓝牙
    closeBLEC(this.deviceId, this.isConnect);
  },
  methods: {
    // 修改设备参数
    upEvent(val, ids) {
      if (!this.isConnect) {
        uni.showToast({ title: "未连接设备", icon: "none", duration: 2000 });
        return;
      }
      writeBLEC(this.deviceId, setValstr(WRITE[ids], val), serverUUID, writeId).then((res) => {
        uni.showToast({ title: "修改成功", icon: "none", duration: 2000 });
        readBLEC(this.deviceId, serverUUID, readId); // 读取数据
      });
    },

    //重启设备
    toSys(code, type) {
      if (!this.isConnect) {
        uni.showToast({ title: "未连接设备", icon: "none", duration: 2000 });
        return;
      }
      writeBLEC(this.deviceId, code, serverUUID, writeId).then((res) => {
        uni.showToast({
          title: type == 1 ? "升级成功" : "重启成功",
          icon: "none",
          duration: 1500,
        });
        // 跳转到首页
        setTimeout(() => {
          uni.reLaunch({ url: "/pages/index/index" });
        }, 1000);
      });
    },

    // 获取配置
    getSetting() {
      if (!this.isConnect) {
        uni.showToast({ title: "未连接设备", icon: "none", duration: 2000 });
        return;
      }
      if (!this.deviceId) {
        uni.showToast({ title: "请选择设备", icon: "none", duration: 2000 });
        return;
      }
      this.optData = [];
      clearInterval(this.timer);
      this.isSet = false;
      // 写入配置编码
      this.timer = setInterval(() => {
        if (this.idx >= CODE.length) {
          clearInterval(this.timer);
          this.idx = 0;
          this.timer = null;
          return;
        }
        writeBLEC(this.deviceId, CODE[this.idx], serverUUID, writeId)
          .then((res) => {
            readBLEC(this.deviceId, serverUUID, readId);
            this.idx++;
          })
          .catch((err) => {
            uni.showToast({ title: "获取失败", icon: "none", duration: 2000 });
            clearInterval(this.timer);
          });
      }, 300);
    },

    // 获取蓝牙设备列表
    getDevice() {
      if (!this.isOpen) {
        uni.showToast({ title: "请打开蓝牙", icon: "none", duration: 500 });
        return;
      }
      // 设备列表
      blueDevices().then((res) => {
        let arr = res.devices || [];
        if (arr.length) {
          this.columns = [objArraySort(arr, "RSSI", "des")] || [[]];
          this.show = true; // 显示
        }
      });
    },
    init() {
      // 初始化蓝牙模块
      openBluetooth()
        .then((res) => {
          this.isOpen = true; // 蓝牙打开
        })
        .catch((err) => {
          this.isOpen = false; // 蓝牙关闭
          uni.showToast({ title: "请打开蓝牙", icon: "none", duration: 500 });
        });
    },
    // 监听返回数据
    changeData() {
      var _that = this;
      // 订阅数据
      notifyBLEC(_that.deviceId, serverUUID, readId);
      // 必须在这里的回调才能获取
      uni.onBLECharacteristicValueChange(function (characteristic) {
        // console.log(`characteristic`, characteristic);
        const hexStr = arrayBufferToString(characteristic.value);
        const value = hexToString(hexStr).slice(2, -2) || "";
        if (value) {
          // console.log("buff解析出来的字符串---------:", value);
          _that.optData.push(value);
          if (_that.optData.length == CODE.length) {
            uni.showToast({ title: "获取成功", icon: "none", duration: 2000 });
            _that.isSet = true;
          }
        }
      });
    },
    // 选中设备
    onConfirm(e) {
      // console.log(`output->e`, e);
      this.name = e.value[0].name || "";
      this.deviceId = e.value[0].deviceId || "";
      this.show = false;
      this.optData = [];
      // 连接设备
      createBLEC(this.deviceId, this.isConnect)
        .then((res) => {
          uni.showToast({ title: "连接成功", icon: "none", duration: 500 });
          this.isConnect = true; // 连接成功
          this.isSet = true; // 获取配置
          this.changeData(); // 监听数据
        })
        .catch((err) => {
          uni.showToast({ title: "连接失败", icon: "none", duration: 500 });
          this.isConnect = false;
        });
    },
    // 取消
    onCancel() {
      this.show = false;
    },
  },
};
</script>

<style lang="scss" scoped>
@keyframes fadeWarning {
  0% {
    opacity: 1;
  }

  50% {
    opacity: 1;
  }

  50.01% {
    opacity: 0;
  }

  100% {
    opacity: 0;
  }
}
.dtu-wrapper {
  height: 100vh;
  width: 100vw;
  background-color: #f4f4f4;
  box-sizing: border-box;
  .title,
  .item {
    min-height: 70rpx;
    line-height: 70rpx;
    font-size: 28rpx;
    border-bottom: #e0e0e0 1px solid;
    padding: 0 20rpx;
    display: flex;
    align-items: center;
    text:nth-child(1) {
      width: 140rpx;
      display: block;
    }
    .uuid {
      text-align: left;
      font-size: 28rpx;
    }

    .icon {
      display: block;
      width: 14rpx;
      height: 14rpx;
      border-radius: 50%;
      margin-left: 30rpx;
      background-color: #5ac725;
    }
    .online {
      // 闪烁动画
      animation: fadeWarning 1s infinite ease-in-out;
    }
    .offline {
      filter: grayscale(100%);
    }
  }
  .item {
    justify-content: space-between;
    margin-bottom: 10rpx;
    ::v-deep .u-textarea {
      padding: 4rpx 10rpx !important;
      background-color: #f4f4f4 !important;
      border: 2rpx #ccc solid;
      margin: 6rpx !important;
      line-height: 40rpx !important;
      min-height: 40rpx !important;
    }
    .btn {
      background-color: #5a8de0;
      color: #fff;
      width: 80rpx;
      height: 50rpx;
      text-align: center;
      line-height: 50rpx;
      font-size: 24rpx;
      border-radius: 8rpx;
    }
  }

  .search {
    height: 80rpx;
    line-height: 80rpx;
    text-align: center;
    font-size: 36rpx;
    font-weight: 550;
    border-bottom: #e0e0e0 1px solid;
  }
  .name {
    height: 60rpx;
    line-height: 60rpx;
    text-align: center;
    font-size: 32rpx;
    text-align: center;
    color: #5a8de0;
  }
  .footer {
    margin-top: 50rpx;
    display: flex;
    justify-content: space-between;
    padding: 0 20rpx;
    width: 100%;
    box-sizing: border-box;
    .u-button,
    ::v-deep .u-button--square {
      width: 30%;
      border: 0 !important;
    }
  }
}

.state-box {
  padding: 10rpx;
  display: flex;
  height: 50rpx;
  border-bottom: 0.5rpx solid #dadbde;
  .icon {
    height: 40rpx;
    width: 40rpx;
    margin-right: 5rpx;
  }
  .online {
    // 闪烁动画
    animation: fadeWarning 1s infinite ease-in-out;
  }
  .offline {
    filter: grayscale(100%);
  }
  .on {
    color: #5ac725;
  }
  .off {
    color: #ccc;
  }
}
</style>
